iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0
Mobile Development

我將成為Swift之強者系列 第 19

Day19 - 仿刻 iOS 鬧鐘實作:新增與編輯鬧鐘(下)

  • 分享至 

  • xImage
  •  

Day19 - 仿刻 iOS 鬧鐘實作:新增與編輯鬧鐘(下)

昨天我們完成了 AddAlarmViewController 的 UI 與資料操作邏輯,可以新增、更新或刪除鬧鐘。
今天要延續下半部分,加入 TableView 的顯示、頁面跳轉,以及通知排程,讓鬧鐘能夠正確設定提醒。


1. TableView 操作與自訂 Cell 顯示

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 4 }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "AddAlarmTableViewCell", for: indexPath) as! AddAlarmTableViewCell
    switch indexPath.row {
    case 0: // 重複
        cell.lbAddAlarm.text = "重複"
        cell.lbPushToRepoeat.isHidden = false
        cell.lbPushToRepoeat.text = repeatTitle()
        cell.accessoryType = .disclosureIndicator
    case 1: // 標籤
        cell.lbAddAlarm.text = "標籤"
        cell.txfRename.isHidden = false
        cell.txfRename.text = alarmname
        cell.txfRename.delegate = self
    case 2: // 提示聲
        cell.lbAddAlarm.text = "提示聲"
        cell.lbPushToSound.isHidden = false
        cell.lbPushToSound.text = selectedSound.isEmpty ? "預設提示聲" : selectedSound
        cell.accessoryType = .disclosureIndicator
    case 3: // 稍後提醒
        cell.lbAddAlarm.text = "稍後提醒~"
        cell.swAddAlarm.isHidden = false
        cell.swAddAlarm.isOn = snoozeEnabled
        cell.swAddAlarm.addTarget(self, action: #selector(snoozeSwitchChanged(_:)), for: .valueChanged)
    default: break
    }
    return cell
}

這裡的 TableView 一共有四列:重複、標籤、提示聲、稍後提醒,分別對應不同的設定項目。


2. 重複天數與提示聲跳轉

@objc func repeatButtonTapped() {
    let repeatVC = RepeatViewController()
    repeatVC.selectedDays = repeatDays
    repeatVC.delegate = self
    navigationController?.pushViewController(repeatVC, animated: true)
}

@objc func soundButtonTapped() {
    let soundVC = SoundViewController()
    soundVC.delegate = self
    soundVC.currentSelectedSound = selectedSound
    navigationController?.pushViewController(soundVC, animated: true)
}

點擊「重複」會跳轉到 RepeatViewController,點擊「提示聲」則會跳轉到 SoundViewController。


3. 排程本地通知

func scheduleNotification(for alarm: AlarmData) {
    let center = UNUserNotificationCenter.current()
    let content = UNMutableNotificationContent()
    content.title = alarm.name
    content.body = "\(alarm.alarmTime) TimeOut!!!"
    content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "\(alarm.sound).mp3"))
    
    let dateComponents = Calendar.current.dateComponents([.hour, .minute], from: formatStringToDate(alarm.alarmTime) ?? Date())
    
    if alarm.repeatDays.contains(true) {
        for (index, isSelected) in alarm.repeatDays.enumerated() where isSelected {
            var triggerDateComponents = dateComponents
            triggerDateComponents.weekday = index + 1
            let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDateComponents, repeats: true)
            let request = UNNotificationRequest(identifier: "\(alarm.creatTime)_\(index)", content: content, trigger: trigger)
            center.add(request)
        }
    } else {
        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
        let request = UNNotificationRequest(identifier: alarm.creatTime, content: content, trigger: trigger)
        center.add(request)
    }
}

這段程式能排程單次鬧鐘與重複鬧鐘,確保時間到時會觸發本地通知。


4. Delegate 回傳

extension AddAlarmViewController: RepeatViewControllerDelegate {
    func didUpdateRepeatDays(_ days: [Bool]) {
        repeatDays = days
        tbvAddAlarm.reloadData()
    }
}

extension AddAlarmViewController: SoundViewControllerDelegate {
    func didSelectSound(_ sound: String) {
        selectedSound = sound
        tbvAddAlarm.reloadData()
    }
}

RepeatViewController 與 SoundViewController 的資料會透過 Delegate 回傳,讓 AddAlarmViewController 即時更新畫面。


小結

今天我們完成了 AddAlarmViewController 的下半部分,包含 TableView 顯示、頁面跳轉以及通知排程。
到這裡為止,新增與編輯鬧鐘的功能已經完整具備。

接下來的教學會開始介紹 RepeatViewController 的設計,讓重複天數的選擇能夠正確運作。



上一篇
Day18 - 仿刻 iOS 鬧鐘實作:新增與編輯鬧鐘(上)
下一篇
Day20 - 天氣API實作:打造資料模型
系列文
我將成為Swift之強者21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言